﻿using System;
using System.Collections.Generic;
using Krile.Kernel;
using Krile.Kernel.Plugin;
using Krile.Kernel.Plugin.Operations;
using Krile.Kernel.WindowsEx;
namespace Twinkle.PluginImpl
{
    public class TOperation : Operation, IAgent
    {
        Plugin parent;
        TService service;
        StatusControl sctrl;
        public TOperation(Plugin p)
        {
            this.parent = p;
            this.service = new TService();
            this.sctrl = new StatusControl();
            Bridge.StatusManager.RegistNewSearchData(typeof(Searchs.SearchTwitterStatus));
            Bridge.StatusManager.RegistNewSearchData(typeof(Searchs.SearchTwitterNormalStatus));
            Bridge.StatusManager.RegistNewSearchData(typeof(Searchs.SearchTwitterDirectMessage));
            Bridge.StatusManager.RegistNewSearchData(typeof(Searchs.SearchTwitterRetweetedStatus));
            Bridge.StatusManager.RegistNewSearchData(typeof(Searchs.SearchTwitterListedStatus));
            Bridge.StatusManager.RegistNewSearchData(typeof(Searchs.SearchTwitterFollowings));
            Bridge.KeyAssign.AddAssignCandidateMethod(
                new Krile.Kernel.Data.Common.KeyAssignCallback((f, s, k) =>
                {
                    if (MessageBoxEx.Show(Lang.Msg.RetweetConfirm, Lang.Msg.RetweetConfirm_Title, MessageBoxEx.MessageBoxExButtons.YesNo, MessageBoxEx.MessageBoxExIcon.Question) == MessageBoxEx.DialogResultEx.Yes)
                    {
                        if (s == null || !(s is Tweak.TStatus))
                            return;
                        if (((Tweak.TStatus)s).User.Protected)
                        {
                            System.Windows.Forms.MessageBox.Show("You can't official retweet this!" + Environment.NewLine + "He/she is a protected user!", "RT Error",
                                 System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                            return;
                        }
                        Bridge.MainForm.SetStatusText("Retweeting...");
                        var a = new Action(() =>
                        {
                            try
                            {
                                TwitterCommonOperation.Retweet(s.UID);
                                Bridge.MainForm.SetStatusText("Retweeted:" + s.User.Name + ">" + s.Text.Original, 3);
                            }
                            catch (Exception ex)
                            {
                                Bridge.MainForm.SetStatusText("RT Error:" + ex.Message, 5);
                            }
                        });
                        a.BeginInvoke((iar) => ((Action)iar.AsyncState).EndInvoke(iar), a);
                    }
                }), Lang.General.RetweetAssignDescription);

            Bridge.KeyAssign.AddAssignCandidateMethod(
                new Krile.Kernel.Data.Common.KeyAssignCallback((f, s, k) =>
                {
                    if (s == null || !(s is Tweak.TStatus))
                        return;
                    if (((Tweak.TStatus)s).User.Protected)
                    {
                        if (MessageBoxEx.Show(
                            "You should not retweet this." + Environment.NewLine +
                            "He/she is a protected user!" + Environment.NewLine +
                            "Do you sure you retweet this?", "RT Warning",
                             MessageBoxEx.MessageBoxExButtons.YesNo,
                              MessageBoxEx.MessageBoxExIcon.Warning) == MessageBoxEx.DialogResultEx.No)
                            return;
                    }
                    TwitterCommonOperation.UnofficialRetweet(s.User.Id, s.Text.Original);
                }), Lang.General.UnofficalRetweetAssignDescription);
            Bridge.KeyAssign.AddAssignCandidateMethod(
                new Krile.Kernel.Data.Common.KeyAssignCallback((f, s, k) =>
                {
                    if (s == null || !(s is Tweak.TStatus))
                        return;
                    TwitterCommonOperation.Quote(s.Id, s.User.Id, s.Text.Original);
                }), Lang.General.QuoteAssignDescription);
        }

        public override string ParentPluginId
        {
            get { return Define.PluginId; }
        }

        public override Operation.OperationTypes OperationType
        {
            get { return OperationTypes.Agent; }
        }

        Dialogs.ApiViewer apv = null;
        public override void Begin()
        {
            Kernel.Init(parent);
            Bridge.ControlManager.RegistInputMethod(new Controls.TInput());
            if (Kernel.Config.Accounts == null || Kernel.Config.Accounts.Length == 0)
            {
                using (var acd = new Dialogs.Account.AccountsManager())
                {
                    acd.ShowDialog();
                }
                if (Kernel.Config.Accounts == null &&
                    MessageBoxEx.Show(
                        Lang.Msg.InactivateConfirm_Context,
                        Lang.Msg.InactivateConfirm,
                        Lang.Msg.InactivateConfirm_Title,
                        MessageBoxEx.MessageBoxExButtons.YesNo,
                        MessageBoxEx.MessageBoxExIcon.Warning) == MessageBoxEx.DialogResultEx.Yes)
                {
                    Bridge.PluginManager.InactivatePlugin(ParentPlugin);
                    return;
                }
            }
            Bridge.MainForm.AddPluginMenu(parent,
                new System.Windows.Forms.ToolStripMenuItem(
                    Lang.General.PluginMenu_AccountsManager, null, (o, e) =>
                    {

                        using (var am = new Dialogs.Account.AccountsManager())
                        {
                            am.ShowDialog();
                        }
                    }));
            Bridge.MainForm.AddPluginMenu(parent,
                new System.Windows.Forms.ToolStripMenuItem(
                    Lang.General.PluginMenu_APIViewer, null, (o, e) =>
                    {
                        if (apv == null)
                        {
                            apv = new Twinkle.Dialogs.ApiViewer();
                            Bridge.MainForm.AppendChild(apv);
                            apv.FormClosed += new System.Windows.Forms.FormClosedEventHandler(apv_FormClosed);
                        }
                        apv.Show();
                    }));
            Common.AutoReceiver.StartThread();
        }

        void apv_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            apv = null;
        }

        public override void Exit()
        {
            Common.StreamManager.EndStreamingAll();
            if (Kernel.Config != null)
                Kernel.Config.SaveConfig();
        }

        public override Dictionary<string, Krile.Kernel.Control.ConfigPage> GetConfigPages()
        {
            var dic = new Dictionary<string, Krile.Kernel.Control.ConfigPage>();
            dic.Add(Lang.General.GeneralSettings, new Dialogs.Config.General());
            dic.Add(Lang.General.BehaviorSettings, new Dialogs.Config.Behavior());
            dic.Add(Lang.General.OuterAPISettings, new Dialogs.Config.OuterAPI());
            return dic;
        }

        public Krile.Kernel.Data.Service HostingService
        {
            get { return this.service; }
        }

        public string InputMethodId
        {
            get { return Define.InputMethodId; }
        }

        public bool IsMasterId(string userid)
        {
            foreach (var a in Kernel.Config.Accounts)
            {
                if (a.UserId == userid)
                    return true;
            }
            return false;
        }

        public Krile.Kernel.Plugin.Operations.AgentElements.IStatusControl Status
        {
            get { return this.sctrl; }
        }

        public StatusControl StatusControl
        {
            get { return this.sctrl; }
        }
    }
}
